from django.shortcuts import render

# Create your views here.
from rest_framework.views import APIView
from urllib.parse import urlencode
from django.conf import settings
from rest_framework.response import Response
from .utils import OauthQQTool

"""前端点击ＱＱ图标，后端拼接一个url返回给前端"""


class QQAuthURLView(APIView):
    """
        分析：
        １．前端根据用户的点击，发送一个ajax请求来获取后端拼接好的url
        2.　我们需要根据QQ的开发文档，拼接一个url
        3.把这个url返回给前端
    """

    def get(self, request):
        """
            # 生成auth_url
            # https://graph.qq.com/oauth2.0/authorize
            # 请求参数请包含如下内容：
            # response_type   必须      授权类型，此值固定为“code”。
            # client_id       必须      申请QQ登录成功后，分配给应用的appid。
            # redirect_uri    必须      成功授权后的回调地址，必须是注册appid时填写的主域名下的地址，建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
            # state           必须      client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
            # scope            可选      scope=get_user_info
        """

        qq = OauthQQTool()
        url = qq.get_oauth_url()

        return Response({"auth_url": url})


"""获取token"""
from rest_framework import status
from urllib.request import urlopen
from urllib.parse import parse_qs
from .models import OAuthQQUser
from .serializers import QQTokenSerializer


class QQTokenView(APIView):
    """
        分析： /oauth/qq/users/?code=xxxxx
        前端通过我们拼接的url向ＱＱ服务器请求数据，用户通过扫描QQ服务器生成的二维码登陆
        用户登陆成功后，ＱＱ服务器会生成一个code给浏览器，后端需要获取这个code向ＱＱ服务器换取token
        根据ＱＱ开发文档找到获取token的方法
        １．前端需要把code信息传递给后端
        ２．后端根据ＱＱ接口文档，同code换取token
    """

    def get(self, request):
        # PC网站：https://graph.qq.com/oauth2.0/token
        # GET
        # grant_type      必须      授权类型，在本步骤中，此值为“authorization_code”。
        # client_id       必须      申请QQ登录成功后，分配给网站的appid。
        # client_secret   必须      申请QQ登录成功后，分配给网站的appkey。
        # code            必须      上一步返回的authorization
        # redirect_uri    必须      与上面一步中传入的redirect_uri保持一致。

        code = request.query_params.get("code")
        if code is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        qq = OauthQQTool()

        try:
            token = qq.get_access_token_by_url(code)

            openid = qq.get_openid_by_token(token)
        except Exception:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 在这里我们已经获取了openid，需要对openid进行绑定
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        # 在绑定时需要判断用户之前是否绑定过，
        except OAuthQQUser.DoesNotExist:
            # 获取一个加密后的openid
            access_token = OAuthQQUser.generic_token_by_openid(openid)
            # 如果没有绑定，则openid加密后返回给前端，并跳转到用户绑定的页面
            return Response({"access_token": access_token})

        else:
            # 如果绑定过则直接让用户登陆，并返回user_id,username,token信息
            from rest_framework_jwt.settings import api_settings
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            pyload = jwt_payload_handler(qq_user.user)

            token = jwt_encode_handler(pyload)

            return Response({
                "username": qq_user.user.username,
                "user_id": qq_user.user.id,
                "token": token
            })

    def post(self, request):
        """
        绑定用户分析：
    1.	用户扫描二维码后，如果用户之前绑定过，则返回登录的信息，如果没有绑定，则由后端返回一个加密的openid(access_token)跳转到绑定用户的页面
    2.	用户填写好表单后，前端需要向后端传递4个数据，手机号，密码，短信验证码，access_token(openid)
    3.	后端得到这四个数据后，需要对其进行相关验证
    4.	后端需要对验证后的数据做判断，如果用户之前注册过，则需要把用户信息和openid进行绑定，如果用户没有注册过，则帮助用户注册再进行绑定
        """
        serializer = QQTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        ## 用户信息绑定后需要跳转到登陆后的页面，所以需要反回username,user_id,token
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        pyload = jwt_payload_handler(user)
        token = jwt_encode_handler(pyload)
        return Response({
            "username": user.username,
            "user_id": user.id,
            "token": token
        })

# 'access_token=0CBA90B0E567527D81C5BF36DBDC25E9&expires_in=7776000&refresh_token=52BB9E899DCE1327C66921F1B93EBC09'
# '0CBA90B0E567527D81C5BF36DBDC25E9'
# openid  = 'C84F374B3E7305D3C6974B1CBB935756'
